/******* 客户端程序client.c ************/

#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<errno.h>
#include<netdb.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<sys/socket.h>
#include<sys/wait.h>
#include<unistd.h>
#include<pthread.h>
#define TRUE 1

static int sockfd;

void recvfromserver()        //接受服务器消息线程入口函数
{
       char mes[1024];
       int nbytes=0;
       while(1)
       {
              memset(mes,0,sizeof(mes));
              nbytes=read(sockfd,mes,sizeof(mes));
              if(nbytes>0)
              {
                     mes[nbytes]='\0';
                     printf("%s\n",mes);
              }
       }
       pthread_exit(NULL);
}
 
int main(int argc, char *argv[])
{
//     int sockfd;
       char buffer[1024];
       struct sockaddr_in server_addr;
       struct hostent *host;
       int portnumber,nbytes;
       char strhost[16];
       char clientname[20];
       char mes[1024];
       int        thr_id;         /* thread ID for the newly createdthread */
       pthread_t  p_thread;       /* thread's structure                     */
       char username[20];         /* 用户名 */
       char password[20];         /* 密码 */
       char ipaddress[16];        /* IP地址 */
       int port;                  /* 端口号 */
       if(argc!=2)
       {
              fprintf(stderr,"Usage:%s username:password@ipaddress:port\a\n",argv[0]);
              exit(1);
       }
       /* 从命令行参数中解析出用户名，密码，IP地址和端口号 */
       char *token = strtok(argv[1], "@"); // 分割用户名和密码部分
       if(token == NULL)
       {
              fprintf(stderr,"Invalid argument format\a\n");
              exit(1);
       }
       sscanf(token, "%[^:]:%s", username, password); // 从用户名和密码部分中分割出用户名和密码
       token = strtok(NULL, "@"); // 分割IP地址和端口号部分
       if(token == NULL)
       {
              fprintf(stderr,"Invalid argument format\a\n");
              exit(1);
       }
       sscanf(token, "%[^:]:%d", ipaddress, &port); // 从IP地址和端口号部分中分割出IP地址和端口号
       /* 根据IP地址获取主机信息 */
       if((host=gethostbyname(ipaddress))==NULL)
       {
              fprintf(stderr,"Gethostnameerror\n");
              exit(1);
       }
       /* 客户程序开始建立 sockfd 描述符 */
       if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
       {
              fprintf(stderr,"SocketError:%s\a\n",strerror(errno));

              exit(1);

       }

       /* 客户程序填充服务端的资料 */
       bzero(&server_addr,sizeof(server_addr));
       server_addr.sin_family=AF_INET;
       server_addr.sin_port=htons(port);
       server_addr.sin_addr=*((struct in_addr *)host->h_addr_list[0]);
       /* 客户程序发起连接请求 */
       if(connect(sockfd,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr))==-1)
       {
              fprintf(stderr,"ConnectError:%s\a\n",strerror(errno));
              exit(1);
       }

       /* 连接成功了 */
       printf("链接服务器成功\n欢迎来到聊天室\n");
       /*存储用户名*/
       /* 发送用户名和密码给服务器验证 */
       sprintf(mes, "%s:%s", username, password);
       if((write(sockfd,mes,sizeof(mes)))==-1)
       {
              fprintf(stderr,"WriteError:%s\n",strerror(errno));
              exit(1);
       }
       fflush(stdin); // 清空输入缓冲区
       printf("\n\n开始聊天吧（\"Quit\"断开连接）\n\n");
       thr_id =pthread_create(&p_thread, NULL, recvfromserver, NULL);
       while(1)
       {
              memset(buffer,0,sizeof(buffer));
              memset(mes,0,sizeof(mes));
              scanf("%s",buffer);            
              strcat(mes,username);
              strcat(mes,":");
              strcat(mes,buffer);
       //     printf("main thread %s\n",mes);
              if((write(sockfd,mes,sizeof(mes)))==-1)
              {
                     fprintf(stderr,"WriteError:%s\n",strerror(errno));
                     exit(1);
              }
              if(strcmp(buffer,"Quit")==0)
              {
                     break;
              }
       }

       /* 结束通讯 */
       close(sockfd);
       exit(0);

}


